/**
 * @file WIFILib.cpp
 * @brief WiFi连接管理库的实现文件
 */

#include "WIFILib.h"

/**
 * @brief 构造函数实现
 * @param ssid WiFi网络名称
 * @param password WiFi网络密码
 */
WIFILib::WIFILib(const char* ssid, const char* password) {
    _ssid = ssid;
    _password = password;
}

/**
 * @brief 初始化WiFi连接
 * @return true: 初始化成功, false: 初始化失败
 */
bool WIFILib::begin() {
    // 检查网络连接
    if (!checkNetworkConnection()) {
        Serial.println("网络连接检查失败");
        return false;
    }
    
    // 等待网络稳定
    if (!waitForNetworkStable()) {
        Serial.println("等待网络稳定超时");
        return false;
    }
    
    return true;
}

/**
 * @brief 设置WiFi事件处理
 * @details 注册WiFi事件回调函数，处理连接、断开、获取IP等事件
 */
void WIFILib::setupWiFiEvents() {
    WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info) {
        switch (event) {
            case SYSTEM_EVENT_STA_CONNECTED:
                Serial.println("WiFi已连接");
                break;
            case SYSTEM_EVENT_STA_DISCONNECTED:
                Serial.println("WiFi断开连接");
                break;
            case SYSTEM_EVENT_STA_GOT_IP:
                Serial.print("获取到IP地址: ");
                Serial.println(WiFi.localIP());
                Serial.print("信号强度: ");
                Serial.print(WiFi.RSSI());
                Serial.println(" dBm");
                break;
            case SYSTEM_EVENT_STA_START:
                Serial.println("WiFi客户端启动");
                break;
            case SYSTEM_EVENT_STA_STOP:
                Serial.println("WiFi客户端停止");
                break;
        }
    });
}

/**
 * @brief 初始化WiFi连接
 * @return true: 初始化成功, false: 初始化失败
 * @details 配置WiFi模式，设置自动重连，并尝试连接
 */
bool WIFILib::initializeWiFi() {
    Serial.println("初始化WiFi连接...");
    
    WiFi.disconnect(true);
    delay(1000);
    WiFi.mode(WIFI_STA);
    WiFi.setAutoReconnect(true);
    WiFi.persistent(true);
    
    setupWiFiEvents();
    
    int retryCount = 0;
    while (retryCount < 5) {
        Serial.printf("尝试连接WiFi (第%d次)...\n", retryCount + 1);
        
        WiFi.begin(_ssid, _password);
        
        unsigned long startTime = millis();
        while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
            Serial.print(".");
            delay(500);
        }
        Serial.println();
        
        if (WiFi.status() == WL_CONNECTED) {
            Serial.println("WiFi连接成功！");
            return true;
        }
        
        Serial.println("WiFi连接失败，准备重试...");
        WiFi.disconnect(true);
        delay(2000);
        retryCount++;
    }
    
    return false;
}

/**
 * @brief 处理WiFi重连
 * @details 当WiFi断开时自动尝试重连
 */
void WIFILib::handleWiFiReconnect() {
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("WiFi连接断开，尝试重连...");
        WiFi.disconnect();
        delay(2000);
        
        WiFi.mode(WIFI_STA);
        WiFi.begin(_ssid, _password);
        
        unsigned long reconnectStartTime = millis();
        while (WiFi.status() != WL_CONNECTED && millis() - reconnectStartTime < 10000) {
            delay(500);
        }
        
        if (WiFi.status() == WL_CONNECTED) {
            Serial.println("WiFi重连成功！");
        } else {
            Serial.println("WiFi重连失败，将在下次循环重试");
        }
    }
}

/**
 * @brief 启动WiFi任务
 * @details 创建并启动WiFi连接维护任务
 */
void WIFILib::startWiFiTask() {
    if (!initializeWiFi()) {
        Serial.println("\nWiFi连接失败！");
        Serial.println("请检查：");
        Serial.println("1. WiFi名称和密码是否正确");
        Serial.println("2. WiFi信号是否足够强");
        Serial.println("3. 路由器是否正常工作");
        return;
    }
    
    while (1) {
        handleWiFiReconnect();
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

/**
 * @brief 检查WiFi连接状态
 * @return true: 已连接, false: 未连接
 */
bool WIFILib::isWiFiConnected() {
    return WiFi.status() == WL_CONNECTED;
}

/**
 * @brief 获取本地IP地址
 * @return IPAddress 本地IP地址
 */
IPAddress WIFILib::getLocalIP() {
    return WiFi.localIP();
}

/**
 * @brief 检查网络连接状态
 * @return true: 网络正常, false: 网络异常
 * @details 检查WiFi连接状态和IP地址
 */
bool WIFILib::checkNetworkConnection() {
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("WiFi未连接");
        return false;
    }
    
    if (WiFi.localIP().toString() == "0.0.0.0") {
        Serial.println("未获取到IP地址");
        return false;
    }
    
    return true;
}

/**
 * @brief 等待网络稳定
 * @param timeout 超时时间(毫秒)
 * @return true: 网络稳定, false: 网络不稳定或超时
 * @details 等待网络连接稳定，包括检查网关可达性
 */
bool WIFILib::waitForNetworkStable(int timeout) {
    unsigned long startTime = millis();
    while (millis() - startTime < timeout) {
        if (checkNetworkConnection()) {
            // 尝试ping网关
            if (WiFi.gatewayIP().toString() != "0.0.0.0") {
                return true;
            }
        }
        delay(100);
    }
    return false;
}
